00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _constraint_renderer_hpp_
00027 #define _constraint_renderer_hpp_
00028
00029 #include <boost/assert.hpp>
00030 #include <boost/format.hpp>
00031
00032 #include "gridpack/expression/expression.hpp"
00033 #include "gridpack/expression/functions.hpp"
00034
00035 namespace gridpack {
00036 namespace optimization {
00037
00038
00039
00040
00041 class ConstraintRenderer
00042 : public ExpressionVisitor
00043 {
00044 public:
00045
00046
00047 ConstraintRenderer(std::ostream& out)
00048 : ExpressionVisitor(), p_out(out)
00049 {}
00050
00051
00052 ~ConstraintRenderer(void)
00053 {}
00054
00055 void visit(IntegerConstant& e)
00056 {
00057 p_out << boost::str(boost::format("%d") % e.value());
00058 }
00059
00060 void visit(RealConstant& e)
00061 {
00062 p_out << boost::str(boost::format("%g") % e.value());
00063 }
00064
00065 void visit(VariableExpression& e)
00066 {
00067 p_out << e.name();
00068 }
00069
00070 void visit(UnaryExpression& e)
00071 {
00072
00073 BOOST_ASSERT(false);
00074 }
00075
00076 void visit(UnaryMinus& e)
00077 {
00078 p_out << "-";
00079 if (e.rhs()->precedence() > e.precedence()) {
00080 p_group(e.rhs());
00081 } else {
00082 e.rhs()->accept(*this);
00083 }
00084 }
00085
00086 void visit(UnaryPlus& e)
00087 {
00088 p_out << "+";
00089 if (e.rhs()->precedence() > e.precedence()) {
00090 p_group(e.rhs());
00091 } else {
00092 e.rhs()->accept(*this);
00093 }
00094 }
00095
00096 void visit(BinaryExpression& e)
00097 {
00098 ExpressionPtr lhs(e.lhs());
00099 ExpressionPtr rhs(e.rhs());
00100
00101 if (lhs->precedence() > e.precedence()) {
00102 p_group(lhs);
00103 } else {
00104 lhs->accept(*this);
00105 }
00106 p_out << " " << e.op() << " ";
00107 if (rhs->precedence() > e.precedence()) {
00108 p_group(rhs);
00109 } else {
00110 rhs->accept(*this);
00111 }
00112 }
00113
00114 void visit(Multiplication& e)
00115 {
00116 this->visit(static_cast<BinaryExpression&>(e));
00117 }
00118
00119 void visit(Division& e)
00120 {
00121 ExpressionPtr lhs(e.lhs());
00122 ExpressionChecker lcheck;
00123 lhs->accept(lcheck);
00124
00125 ExpressionPtr rhs(e.rhs());
00126 ExpressionChecker rcheck;
00127 rhs->accept(rcheck);
00128
00129
00130
00131 if (!lcheck.isConstant) {
00132 BOOST_ASSERT_MSG(false, "ConstraintRenderer: Invalid RHS to Division");
00133 }
00134
00135
00136
00137
00138 if (lhs->precedence() > e.precedence()) {
00139 p_group(lhs);
00140 } else {
00141 lhs->accept(*this);
00142 }
00143 p_out << "/";
00144 rhs->accept(*this);
00145 }
00146
00147 void visit(Addition& e)
00148 {
00149 this->visit(static_cast<BinaryExpression&>(e));
00150 }
00151
00152 void visit(Subtraction& e)
00153 {
00154 ExpressionPtr lhs(e.lhs());
00155 ExpressionPtr rhs(e.rhs());
00156
00157 if (lhs->precedence() > e.precedence()) {
00158 p_group(lhs);
00159 } else {
00160 lhs->accept(*this);
00161 }
00162 p_out << " - ";
00163 if (rhs->precedence() >= e.precedence()) {
00164 p_group(rhs);
00165 } else {
00166 rhs->accept(*this);
00167 }
00168 }
00169 void visit(Exponentiation& e)
00170 {
00171 ExpressionPtr lhs(e.lhs());
00172
00173 ExpressionPtr rhs(e.rhs());
00174 ExpressionChecker rcheck;
00175
00176 if (lhs->precedence() > e.precedence()) {
00177 p_group(lhs);
00178 } else {
00179 lhs->accept(*this);
00180 }
00181 p_out << " ^ ";
00182 rhs->accept(*this);
00183 }
00184
00185 void visit(Constraint& e)
00186 {
00187 ExpressionPtr lhs(e.lhs());
00188 ExpressionPtr rhs(e.rhs());
00189
00190 if (lhs->precedence() > e.precedence()) {
00191 p_group(lhs);
00192 } else {
00193 lhs->accept(*this);
00194 }
00195 p_out << " " << e.op() << " ";
00196 if (rhs->precedence() > e.precedence()) {
00197 p_group(rhs);
00198 } else {
00199 rhs->accept(*this);
00200 }
00201 }
00202
00203 void visit(LessThan& e)
00204 {
00205 this->visit(static_cast<Constraint&>(e));
00206 }
00207
00208 void visit(LessThanOrEqual& e)
00209 {
00210 this->visit(static_cast<Constraint&>(e));
00211 }
00212
00213 void visit(GreaterThan& e)
00214 {
00215 this->visit(static_cast<Constraint&>(e));
00216 }
00217
00218 void visit(GreaterThanOrEqual& e)
00219 {
00220 this->visit(static_cast<Constraint&>(e));
00221 }
00222
00223 void visit(Equal& e)
00224 {
00225 this->visit(static_cast<Constraint&>(e));
00226 }
00227
00228 void visit(Function& f)
00229 {
00230 bool first(true);
00231 p_out << f.name();
00232 p_out << "(";
00233 BOOST_FOREACH(const ExpressionPtr a, f.args()) {
00234 if (!first) {
00235 p_out << ", ";
00236 }
00237 first = false;
00238 a->accept(*this);
00239 }
00240 p_out << ")";
00241 }
00242
00243 protected:
00244
00245
00246 std::ostream& p_out;
00247
00248
00249 virtual void p_group(ExpressionPtr e)
00250 {
00251 p_out << "(";
00252 e->accept(*this);
00253 p_out << ")";
00254 }
00255
00256
00257 };
00258
00259
00260
00261 }
00262 }
00263
00264 #endif